﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net.Http.Formatting;
using System.Web.Http.ModelBinding;
using umbraco.BusinessLogic.Actions;
using Umbraco.Core;
using Umbraco.Core.Persistence;
using Umbraco.Web.Models.Trees;
using Umbraco.Web.Mvc;
using Umbraco.Web.Trees;
using Umbraco.Web.WebApi.Filters;
using UmbracoExtending.Dealer.Model.Dealer;
using UmbracoExtending.Dealer.Model.Config;
using UmbracoExtending.Dealer.Model.District;

namespace UmbracoExtending.Dealer.Controller
{
    /// <summary>
    /// 经销商树菜单
    /// </summary>
    [Tree("dealer", "dealerListAlias", "Dealer List")]
    [PluginController("DealerSection")]
    public class DealerTreeController : TreeController
    {
        protected override MenuItemCollection GetMenuForNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))] FormDataCollection queryStrings)
        {
            var menu = new MenuItemCollection();
            var textService = ApplicationContext.Services.TextService;

            //如果是根级，不显示删除和刷新菜单
            if (id == Constants.System.Root.ToInvariantString())
            {
                DealerConfiguration dealerConfiguration = this.GetDealerConfiguration();
                //如果配置不为空，显示完整的三个菜单
                if (null != dealerConfiguration && !string.IsNullOrEmpty(dealerConfiguration.MapAppKey) && !string.IsNullOrEmpty(dealerConfiguration.MapPlatform))
                {
                    MenuItem mi = new MenuItem();
                    //如果是管理员，多显示配置弹窗和导入菜单
                    if (Security.CurrentUser.Groups.Any(x => x.Alias == "admin"))
                    {   
                        string configurationText = textService.Localize("actions/configuration", CultureInfo.CurrentCulture);
                        mi = new MenuItem("configuration", configurationText) { Icon = "settings" };
                        menu.Items.Add(mi);

                        /*
                     string importText = textService.Localize("actions/import", CultureInfo.CurrentCulture);
                        mi = new MenuItem() { Name = importText, Icon = "traffic" };
                        mi.NavigateToRoute("/dealer/dealerListAlias/create");
                        menu.Items.Add(mi);    
                     
                     */
                    }

                    var rootRefreshText = textService.Localize("actions/refresh", CultureInfo.CurrentCulture);
                    menu.Items.Add<RefreshNode, ActionRefresh>(rootRefreshText, true);

                    //如果有配置，添加创建按钮
                    string createText = textService.Localize("actions/createDealer", CultureInfo.CurrentCulture);
                    mi = new MenuItem() { Name = createText,Icon= "shopping-basket" };
                    mi.NavigateToRoute("/dealer/dealerListAlias/create");
                    menu.Items.Add(mi);

                    return menu;
                }

                //如果配置为空，看看是不是管理员
                if (Security.CurrentUser.Groups.Any(x => x.Alias == "admin"))
                {
                    //如果是管理员
                    string configurationText = textService.Localize("actions/configuration", CultureInfo.CurrentCulture);
                    MenuItem mi = new MenuItem("configuration", configurationText) { Icon = "settings" };
                    menu.Items.Add(mi);
                }
                return menu;
            }

            //如果没有配置，是不会有子集出现的
            var refreshText = textService.Localize("actions/refresh", CultureInfo.CurrentCulture);
            menu.Items.Add<RefreshNode, ActionRefresh>(refreshText, true);

            var deleteText = textService.Localize("actions/delete", CultureInfo.CurrentCulture);
            menu.Items.Add<ActionDelete>(deleteText, true);

            return menu;
        }

        /// <summary>
        /// 返回节点树
        /// </summary>
        /// <param name="id">点击进入的菜单id</param>
        /// <param name="queryStrings">查询参数</param>
        /// <returns></returns>
        protected override TreeNodeCollection GetTreeNodes(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))] FormDataCollection queryStrings)
        {
            var nodes = new TreeNodeCollection();
            DealerConfiguration dealerConfiguration = this.GetDealerConfiguration();
            if (null != dealerConfiguration && !string.IsNullOrEmpty(dealerConfiguration.MapAppKey))
            {
                var db = ApplicationContext.DatabaseContext.Database;
                if (id == Constants.System.Root.ToInvariantString())
                {
                    ///这里是第一层节点
                    var provinces = this.GetProvinces();
                    if (null != provinces && provinces.Count() > 0)
                    {
                        foreach (var province in provinces)
                        {
                            var node = CreateTreeNode("province_" + province.Code, "-1"
                                , queryStrings, province.Name, "icon-map", true
                                , "/dealer/dealerListAlias/statistics/province_" + province.Code);
                            nodes.Add(node);
                        }
                    }
                }
                else if (id.StartsWith("province_"))
                {
                    string provinceCode = id.Replace("province_", "");
                    List<DistrictSimple> citys = null;
                    string prefix = "city_";
                    if (dealerConfiguration.SimpleMode.Equals("y") && LocalConfiguration.MunicipalityCode.IndexOf(provinceCode) >= 0)
                    {
                        //开启了简洁模式，并且是直辖市
                        citys = this.GetDistrictsByProvince(provinceCode);
                        prefix = "district_";
                    }
                    else
                    {
                        citys = this.GetCitys(provinceCode);
                    }


                    if (null != citys && citys.Count() > 0)
                    {
                        bool hideChild = dealerConfiguration.SimpleMode.Equals("y") && dealerConfiguration.ListView.Equals("y");

                        foreach (var city in citys)
                        {
                            var node = CreateTreeNode(prefix + city.Code, id
                                , queryStrings, city.Name, "icon-map", !hideChild
                                , (hideChild ? "/dealer/dealerListAlias/list/" + prefix + city.Code : "/dealer/dealerListAlias/statistics/" + prefix + city.Code));

                            nodes.Add(node);
                        }
                    }

                }
                else if (id.StartsWith("city_"))
                {
                    string cityCode = id.Replace("city_", "");
                    if (dealerConfiguration.SimpleMode.Equals("y"))
                    {
                        var dealers = this.GetDealersByCity(cityCode);
                        if (null != dealers && dealers.Count() > 0)
                        {
                            foreach (var dealer in dealers)
                            {
                                var node = CreateTreeNode("dealer_" + dealer.Id, id
                                    , queryStrings, dealer.StoreName, "icon-shopping-basket", false);
                                nodes.Add(node);
                            }
                        }
                    }
                    else
                    {
                        var districts = this.GetDistrictsByProvince(cityCode);
                    }
                }
                else
                {
                    string districtCode = id.Replace("district_", "");
                    var dealers = this.GetDealers(districtCode);
                    if (null != dealers && dealers.Count() > 0)
                    {
                        foreach (var dealer in dealers)
                        {
                            var node = CreateTreeNode("dealer_" + dealer.Id, id
                                , queryStrings, dealer.StoreName, "icon-shopping-basket", false);
                            nodes.Add(node);
                        }
                    }
                }
            }
            return nodes;
        }

        /// <summary>
        /// 获取默认的配置对象
        /// </summary>
        /// <returns></returns>
        private DealerConfiguration GetDealerConfiguration()
        {
            var db = ApplicationContext.DatabaseContext.Database;
            var query = new Sql()
                .Select("Id, MapPlatform, MapAppKey, ListView, ShowWarning, SimpleMode, ShowTwoLayers")
                .From("[umbracoExtendingDealerConfig]")
                .OrderBy("Id");
            return db.Fetch<DealerConfiguration>(query).FirstOrDefault();
        }

        /// <summary>
        /// 获取默认的省份聚合信息
        /// </summary>
        /// <returns></returns>
        private List<DistrictSimple> GetProvinces()
        {
            var db = ApplicationContext.DatabaseContext.Database;
            var query = new Sql().Select("ProvinceCode as Code, ProvinceName as Name")
                        .From("[V_umbracoExtendingDealer]")
                        .GroupBy(new string[] { "ProvinceCode", "ProvinceName" })
                        .OrderBy("[Name]");
            return db.Fetch<DistrictSimple>(query);
        }

        /// <summary>
        /// 获取城市
        /// </summary>
        /// <param name="provinceCode">省份编码</param>
        /// <returns></returns>
        private List<DistrictSimple> GetCitys(string provinceCode)
        {
            var db = ApplicationContext.DatabaseContext.Database;
            var query = new Sql().Select("CityCode as Code, CityName as Name")
                        .From("[V_umbracoExtendingDealer]")
                        .Where("[ProvinceCode] = @0", provinceCode)
                        .GroupBy(new string[] { "CityCode", "CityName" })
                        .OrderBy("[Name]");
            return db.Fetch<DistrictSimple>(query);
        }

        /// <summary>
        /// 根据省份编码直接获取区县
        /// </summary>
        /// <param name="provinceCode"></param>
        /// <returns></returns>
        private List<DistrictSimple> GetDistrictsByProvince(string provinceCode)
        {
            var db = ApplicationContext.DatabaseContext.Database;
            var query = new Sql().Select("DistrictCode as Code, DistrictName as Name")
                        .From("[V_umbracoExtendingDealer]")
                        .Where("[ProvinceCode] = @0", provinceCode)
                        .GroupBy(new string[] { "DistrictCode", "DistrictName" })
                        .OrderBy("[Name]");
            return db.Fetch<DistrictSimple>(query);
        }

        /// <summary>
        /// 获取区县
        /// </summary>
        /// <param name="cityCode"></param>
        /// <returns></returns>
        private List<DistrictSimple> GetDistricts(string cityCode)
        {
            var db = ApplicationContext.DatabaseContext.Database;
            var query = new Sql().Select("DistrictCode as Code, DistrictName as Name")
                        .From("[V_umbracoExtendingDealer]")
                        .Where("[CityCode] = @0", cityCode)
                        .GroupBy(new string[] { "DistrictCode", "DistrictName" })
                        .OrderBy("[Name]");
            return db.Fetch<DistrictSimple>(query);
        }

        /// <summary>
        /// 根据区县获取经销商
        /// </summary>
        /// <param name="districtCode"></param>
        /// <returns></returns>
        private List<DealerItem> GetDealers(string districtCode)
        {
            var db = ApplicationContext.DatabaseContext.Database;
            var query = new Sql().Select("Id, Province, City, District, Address, StoreName, ResponsiblePerson, ContactNumber, Lat, Lng, IsMistake")
                        .From("[V_umbracoExtendingDealer]")
                        .Where("[DistrictCode] = @0", districtCode)
                        .OrderBy("[StoreName]");
            return db.Fetch<DealerItem>(query);
        }

        /// <summary>
        /// 根据省份获取经销商
        /// </summary>
        /// <param name="cityCode"></param>
        /// <returns></returns>
        private List<DealerItem> GetDealersByCity(string cityCode)
        {
            var db = ApplicationContext.DatabaseContext.Database;
            var query = new Sql().Select("Id, Province, City, District, Address, StoreName, ResponsiblePerson, ContactNumber, Lat, Lng, IsMistake")
                        .From("[V_umbracoExtendingDealer]")
                        .Where("[CityCode] = @0", cityCode)
                        .OrderBy("[StoreName]");
            return db.Fetch<DealerItem>(query);
        }
    }
}
